RustのHyperで(req, res)=>voidなハンドラーを使いたい
#Hyper #Rust #HTTP
RustのHyperでNode.jsライクなハンドラーは0.10だと使えていた様子などにも関係。
以下のreq_res_handler()を使ってFnMut(Request<Body>, oneshot::Sender<Response<Body>>) -> ()をservice_fnで使える関数の形に変換している。
code:rs
// NOTE: oneshot::Receiver can be Future
fn req_res_handler<F>(mut handler: F) -> impl FnMut(Request<Body>) -> oneshot::Receiver<Response<Body>> where 
F: FnMut(Request<Body>, oneshot::Sender<Response<Body>>) -> ()
{
move |req| {
let (res_sender, res_receiver) = oneshot::channel::<Response<Body>>();
handler(req, res_sender);
res_receiver
}
}
使い方の例
code:rs
let handler = req_res_handler(move |req, res_sender| {
// ... reqから読み取ったり、res_senderでレスポンス返したりする ...
});
service_fn(handler)
FnMut(Request<Body>, oneshot::Sender<Response<Body>>) -> ()はNode.jsで言えば、(req, res) => voidに対応する。
oneshot::Sender<Response<Body>>には.send(response)とすれば好きなタイミングでレスポンスを返すようにできる。
oneshot::Receiver<Response<Body>>はFuture<Item=Response<Body>>になってくれる感じ
実際にPiping Serverで使っている場所
https://github.com/nwtgck/piping-server-rust/blob/9727f184f3a8493d1ab89b8ee7bd5872870d3af1/src/main.rs#L61-L124
要調査:ブロッキングして多くのリクエストさばけなくならないかどうか